//package com.scnu.hachimi.manager;
//
//import com.scnu.hachimi.controller.KeyboardListener;
//import com.scnu.hachimi.element.*;
//import com.scnu.hachimi.show.GameJPanel;
//
//import java.awt.*;
//import java.awt.event.KeyEvent;
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.*;
//
//import static com.scnu.hachimi.manager.MapLoader.getMap;
//
//public class ObjectManager extends Thread {
//    public int width = 800;
//    public int height = 600;
//
//    int Alive;
//
//    public boolean stop = false;
//    private boolean restart = false;
//    private int stopOption = 1;
//    public boolean end = false;
//    private boolean win = true;
//
//    public int diff;
//    private int playerNum;
//
//    public GameJPanel gjp;
//
//    public String mapFilePath;
//
//    public int destroyCount = 0;
//    public long useTime = 0, st;
//
//    private boolean running = true;
//
//    private int player1HP, player2HP, player1A, player2A, bossHP, botHP, eliteHP, eliteA, bossA, eliteS, bossS, eliteL, bossL;
//    private int batch = 1;
//
//    public CopyOnWriteArrayList<Bot> bot = new CopyOnWriteArrayList<>();
//    public CopyOnWriteArrayList<Player> player = new CopyOnWriteArrayList<>();
//    public CopyOnWriteArrayList<Bullet> bullet = new CopyOnWriteArrayList<>();
//    public CopyOnWriteArrayList<Wall> wall = new CopyOnWriteArrayList<>();
//    public CopyOnWriteArrayList<Base> base = new CopyOnWriteArrayList<>();
//    public CopyOnWriteArrayList<River> river = new CopyOnWriteArrayList<>();
//    public CopyOnWriteArrayList<Boom> boom = new CopyOnWriteArrayList<>();
//    public CopyOnWriteArrayList<String> stopImage = new CopyOnWriteArrayList<>();
//    public CopyOnWriteArrayList<String> endImage = new CopyOnWriteArrayList<>();
//
//    private Map<String, List<Point>> mapData = new HashMap<>();
//
//
////    public List<Player> player = new ArrayList<>();
////    public List<Bullet> bullet = new ArrayList<>();
////    public List<Bot> bot = new ArrayList<>();
////    public List<Wall> wall = new ArrayList<>();
//
//    public ConcurrentHashMap<Integer, Boolean> kb = new ConcurrentHashMap<>();
//    public ConcurrentHashMap<Integer, Long> keyTimeSet = new ConcurrentHashMap<>();
//
//    private double fn = 0, ti;
//
//    public ObjectManager(int playerNum, int diff, String mapFilePath) {
//
//        this.playerNum = playerNum;
//        this.diff = diff;
//        this.mapFilePath = mapFilePath;
//        this.Alive = playerNum;
//
//
//        // 初始化所有按键事件的初始值为false
//        for (int keyCode = 0; keyCode < 256; keyCode++) {
//            kb.put(keyCode, false);
//        }
//
//        checkStopImage();
//    }
//
//
//    private void updateBullets() {
//        for (Bullet b : bullet) {
//            b.move();
//        }
//    }
//
//    private void updatePlayer() {
//        //移动监听
//        //w 87 a 65 s 83 d 68
//        int key = -1;
//        long time = 0;
//        Direction d = Direction.UP;
//
//        if (player.get(0).isAlive) {
//            if (kb.get(KeyEvent.VK_W) && (keyTimeSet.get(KeyEvent.VK_W) > time)) {
//                time = keyTimeSet.get(KeyEvent.VK_W);
//                key = KeyEvent.VK_W;
//                d = Direction.UP;
//            }
//            if (kb.get(KeyEvent.VK_A) && keyTimeSet.get(KeyEvent.VK_A) > time) {
//                time = keyTimeSet.get(KeyEvent.VK_A);
//                key = KeyEvent.VK_A;
//                d = Direction.LEFT;
//            }
//            if (kb.get(KeyEvent.VK_S) && keyTimeSet.get(KeyEvent.VK_S) > time) {
//                time = keyTimeSet.get(KeyEvent.VK_S);
//                key = KeyEvent.VK_S;
//                d = Direction.DOWN;
//            }
//            if (kb.get(KeyEvent.VK_D) && keyTimeSet.get(KeyEvent.VK_D) > time) {
//                time = keyTimeSet.get(KeyEvent.VK_D);
//                key = KeyEvent.VK_D;
//                d = Direction.RIGHT;
//            }
//            if (key != -1) {
//                player.get(0).setImg(d);
//                player.get(0).move(d);
//            }
//
//            if (kb.get(KeyEvent.VK_SPACE)) {
//                player.get(0).attack();
//            }
//        }
//
//        if (playerNum == 2 && player.get(1).isAlive) {
//            key = -1;
//            time = 0;
//            //player2,上下左右移动，Enter攻击
//            if (kb.get(KeyEvent.VK_UP) && keyTimeSet.get(KeyEvent.VK_UP) > time) {
//                time = keyTimeSet.get(KeyEvent.VK_UP);
//                key = KeyEvent.VK_UP;
//                d = Direction.UP;
//            }
//            if (kb.get(KeyEvent.VK_DOWN) && keyTimeSet.get(KeyEvent.VK_DOWN) > time) {
//                time = keyTimeSet.get(KeyEvent.VK_DOWN);
//                key = KeyEvent.VK_DOWN;
//                d = Direction.DOWN;
//            }
//            if (kb.get(KeyEvent.VK_LEFT) && keyTimeSet.get(KeyEvent.VK_LEFT) > time) {
//                time = keyTimeSet.get(KeyEvent.VK_LEFT);
//                key = KeyEvent.VK_LEFT;
//                d = Direction.LEFT;
//            }
//            if (kb.get(KeyEvent.VK_RIGHT) && keyTimeSet.get(KeyEvent.VK_RIGHT) > time) {
//                time = keyTimeSet.get(KeyEvent.VK_RIGHT);
//                key = KeyEvent.VK_RIGHT;
//                d = Direction.RIGHT;
//            }
//            if (key != -1) {
//                player.get(1).setImg(d);
//                player.get(1).move(d);
//            }
//
//            if (kb.get(KeyEvent.VK_NUMPAD0)) {
//                player.get(1).attack();
//            }
//
//        }
//
//    }
//
//    private void updateBots() {
//        for (Bot b : bot) {
//            b.autoMoveAndAttack();
//        }
//    }
//
//    //难度0：5，5，10
//    //难度1：10，15，15
//    //难度2：15，20，20
//
//    private int[] bc = {5, 5, 10, 10, 15, 15, 15, 20, 20};
//
//    private void loadMap(String filePath) {
//        try {
//            mapData = getMap(filePath);
//            for (String terrainType : mapData.keySet()) {
//                List<Point> points = mapData.get(terrainType);
//                if (terrainType.equals("BRICK"))
//                    for (Point point : points) {
//                        wall.add(new Wall(terrainType, point.x, point.y, 1, false));
//                    }
//
//                if (terrainType.equals("GRASS")) {
//                    for (Point point : points) {
//                        wall.add(new Wall(terrainType, point.x, point.y, 1, true));
//                    }
//                }
//
//                if (terrainType.equals("IRON"))
//                    for (Point point : points) {
//                        wall.add(new Iron(terrainType, point.x, point.y, 1, false));
//                    }
//
//
//                if (terrainType.equals("base"))
//                    for (Point point : points) {
//                        base.add(new Base(terrainType, point.x, point.y, 10));
//                    }
//
//                if (terrainType.equals("RIVER"))
//                    for (Point point : points) {
//                        river.add(new River(terrainType, point.x, point.y, 1));
//                    }
//
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    //碰撞检测, Tank-Wall Bullet-Tank Bullet-Wall Tank-边界  Bullet-边界
//
//    private void checkBW() {
//        List<Bullet> removeBullet = new ArrayList<>();
//        List<Wall> removeWall = new ArrayList<>();
//        for (Bullet b : bullet) {
//            for (Wall w : wall) {
//                if (b.getRect().intersects(w.getRect())) {
//                    if (!w.canThrough) removeBullet.add(b);
//
//                    if (w instanceof Iron) {
//                        //TODO 等级高了才能摧毁铁墙
//                    } else {
//                        w.hp -= b.atk;
//                        if (w.hp <= 0) removeWall.add(w);
//                    }
//                }
//            }
//        }
//
//        bullet.removeAll(removeBullet);
//        wall.removeAll(removeWall);
//    }
//
//    private void checkBB() {
//        List<Bullet> removeBullet = new ArrayList<>();
//        for (Bullet b : bullet) {
//            for (Base base : base) {
//                if (b.getRect().intersects(base.getRect())) {
//                    base.hp -= b.atk;
//                    removeBullet.add(b);
//                    boom.add(new Boom("boom", b.getX(), b.getY(), 20, 20));
//                    if (base.hp <= 0) {
//                        end = true;
//                        win = false;
//                    }
//                }
//            }
//        }
//        bullet.removeAll(removeBullet);
//    }
//
//    //在全屏随机部署bot，先检测碰撞，如果没有则部署
//    private void addBots(int count, int hp, int h, int w, Color color, int bulletSpeed, int bulletSize, int loadTime, int speed) {
//        for (int i = 0; i < count; i++) {
//            Bot bot = new Bot("bot_up", 0, 0, w, h, speed, hp, loadTime, bulletSpeed, bulletSize,
//                    "bot_up", "bot_down", "bot_left", "bot_right",
//                    color, hp, this);
//
//            deployTank(bot);
//        }
//    }
//
//    private void deployTank(Tank tank) {
//        while (true) {
//            int x = (int) (Math.random() * (width - tank.getW()));
//            int y = (int) (Math.random() * (height - tank.getH()));
//
//            tank.setX(x);
//            tank.setY(y);
//
//            if (!tank.checkWallBorder(Direction.UP)) {
//
//                if (tank instanceof Player) {
//                    player.add((Player) tank);
//                    System.out.println("Player added");
//                } else if (tank instanceof Bot) {
//                    bot.add((Bot) tank);
//                    System.out.println("Bot added");
//                }
//                break;
//            }
//        }
//    }
//
//
//    //部署玩家
//    private void addPlayer() {
//        //如果是单人模式，则只部署玩家1，如果没有玩家1，就选择玩家2
//        if (playerNum == 1) {
//            if (mapData.get("player1") != null) {
//                for (Point point : mapData.get("player1")) {
//                    player.add(new Player("player1", point.x, point.y, 40, 40, 3, 1, 500, 5, 10, "player1_up", "player1_down", "player1_left", "player1_right", Color.BLUE, 1, this));
//                }
//            }
//            else if (mapData.get("player2") != null) {
//                for (Point point : mapData.get("player2")) {
//                    player.add(new Player("player2", point.x, point.y, 40, 40, 3, 1, 500, 5, 10, "player2_up", "player2_down", "player2_left", "player2_right", Color.RED, 2, this));
//                }
//            }
//            else {
//                Player p1 = new Player("player1", 0, 0, 40, 40, 3, 1, 500, 5, 10, "player1_up", "player1_down", "player1_left", "player1_right", Color.BLUE, 1, this);
//                deployTank(p1);
//            }
//        }
//        //如果是双人模式，部署玩家1和2，如果只有一个玩家，则另一个玩家位置随机
//        else if (playerNum == 2) {
//            if (mapData.get("player1") != null) {
//                for (Point point : mapData.get("player1")) {
//                    player.add(new Player("player1", point.x, point.y, 40, 40, 3, 1, 500, 5, 10, "player1_up", "player1_down", "player1_left", "player1_right", Color.BLUE, 1, this));
//                }
//            }
//            else {
//                Player p1 = new Player("player1", 0, 0, 40, 40, 3, 1, 500, 5, 10, "player1_up", "player1_down", "player1_left", "player1_right", Color.BLUE, 1, this);
//                deployTank(p1);
//            }
//            if (mapData.get("player2") != null) {
//                for (Point point : mapData.get("player2")) {
//                    player.add(new Player("player2", point.x, point.y, 40, 40, 3, 1, 500, 5, 10, "player2_up", "player2_down", "player2_left", "player2_right", Color.RED, 2, this));
//                }
//            }
//            else {
//                Player p2 = new Player("player2", 0, 0, 40, 40, 3, 1, 500, 5, 10, "player2_up", "player2_down", "player2_left", "player2_right", Color.RED, 2, this);
//                deployTank(p2);
//            }
//        }
//
//    }
//
//    private void checkBT() {
//        List<Bullet> removeBullet = new ArrayList<>();
//        List<Bot> removeBot = new ArrayList<>();
//        for (Bullet b : bullet) {
//
//            //如果超出范围则删除
//            if (b.getX() < -b.getH() || b.getX() > width || b.getY() < -b.getH() || b.getY() > height) {
//                removeBullet.add(b);
//                continue;
//            }
//
//            boolean hit = false;
//
//            for (Player p : player) {
//                if (b.getRect().intersects(p.getRect()) && !b.isPlayer) {
//                    removeBullet.add(b);
//                    p.hp -= b.atk;
//                    if (p.hp <= 0) {
//                        boom.add(new Boom("boom", b.getX(), b.getY(), 30, 30));
//                        p.isAlive = false;
//                        Alive--;
//                        if (Alive <= 0) {
//                            win = false;
//                            end = true;
//                        }
//                    } else {
//                        boom.add(new Boom("boom", b.getX(), b.getY(), 2, 2));
//                    }
//                    hit = true;
//                }
//            }
//            if (hit) continue;
//
//            for (Bot bt : bot) {
//                if (b.getRect().intersects(bt.getRect()) && b.isPlayer) {
//                    removeBullet.add(b);
//                    bt.hp -= b.atk;
//                    if (bt.hp <= 0) {
//                        removeBot.add(bt);
//                        destroyCount++;
//                        boom.add(new Boom("boom", b.getX(), b.getY(), 30, 30));
//                    } else {
//                        boom.add(new Boom("boom", b.getX(), b.getY(), 2, 2));
//                    }
//                }
//            }
//        }
//        bullet.removeAll(removeBullet);
//        bot.removeAll(removeBot);
//
//        if (bot.isEmpty()) {
//            if (batch <= 3) {
//                addEnemies();
//                batch++;
//            } else end = true;
//        }
//    }
//
//    private void checkBoom() {
//        List<Boom> removeBoom = new ArrayList<>();
//        for (Boom b : boom) {
//            if (b.life <= 0) {
//                removeBoom.add(b);
//            }
//            b.move();
//        }
//        boom.removeAll(removeBoom);
//    }
//
//    private void addEnemies() {
//        //根据难度，波次添加敌人
//        int botCount = bc[(batch - 1) * 3 + diff]; //小兵数量
//
//        addBots(botCount, botHP, 40, 40, Color.BLUE, 5, 5, 500, 2);
//
//        if (batch == 2) {
//            //添加elite
//            if (mapData.get("elite") != null) {
//                for (Point p : mapData.get("elite")) {
//                    bot.add(new Bot("elite", p.x, p.y, 40, 40, eliteS, eliteA, eliteL, 5, 10, "elite_up", "elite_down", "elite_left", "elite_right", Color.RED, eliteHP, this));
//                }
//            }
//        }
//
//        if (batch == 3) {
//            //添加boss
//            if (mapData.get("BOSS") != null) {
//                for (Point p : mapData.get("BOSS")) {
//                    bot.add(new Bot("BOSS", p.x, p.y, 40, 40, bossS, bossA, bossL, 5, 10, "BOSS_up", "BOSS_down", "BOSS_left", "BOSS_right", Color.RED, bossHP, this));
//                }
//            }
//        }
//    }
//
//
//    //根据键盘按下状态刷新所有逻辑
//    private void updateAll() {
//
//        updateBullets();
//
//        checkBW();
//
//        checkBT();
//
//        checkBB();
//
//        updatePlayer();  //TW
//
//        updateBots();  //TW
//
//        checkBoom();
//
//        fn++;
//
////        System.out.println(fn / ((System.currentTimeMillis() - ti) / 1000));
//    }
//
//    private void checkStopImage() {
//        stopImage.clear();
//        this.stopImage.add("sp" + Integer.toString(stopOption));
//    }
//
//    boolean w = true, s = true;  //记录w和s是否松开过，true是为可用
//
//    private void checkStopState() {
//        if (kb.get(KeyEvent.VK_ESCAPE)) stop = true;
//
//        if (stop) {//监听ws键改变state
//            useTime += System.currentTimeMillis() - st;
//            st = System.currentTimeMillis();
//            if (kb.get(KeyEvent.VK_W)) {
//                if (w) {
//                    stopOption = stopOption > 1 ? stopOption - 1 : stopOption;
//                    checkStopImage();
//                    w = false;
//                }
//            } else w = true;
//
//            if (kb.get(KeyEvent.VK_S)) {
//                if (s) {
//                    stopOption = stopOption < 3 ? stopOption + 1 : stopOption;
//                    checkStopImage();
//                    s = false;
//                }
//            } else s = true;
//
//            //enter
//            if (kb.get(KeyEvent.VK_ENTER)) {
//                stop = false;
//
//                if (stopOption == 2) {
//                    //重来
//                    restart = true;
//                }
//                if (stopOption == 3) {
//                    //退出
//                    gjp.quit(playerNum);
//                    gjp.stopGame();
//                    stopRunning();
//                }
//            }
//        }
//    }
//
//    private void initGame() {
//        loadMap("map/" + mapFilePath);
//        Alive = playerNum;
//        addPlayer();
//
////        addPlayer();
////        addBots(5, 2, 40, 40, Color.BLUE, 5, 10, 1000, 2);
//    }
//
//    private void checkEnd() {
//        if (end) {
//
//            if (useTime == 0)
//                useTime += System.currentTimeMillis() - st;
//
//            if (win && endImage.isEmpty()) {
//                endImage.add("win");
//            } else if (!win && endImage.isEmpty()) {
//                endImage.add("lose");
//            }
//
//            //监听Enter键
//            if (kb.get(KeyEvent.VK_ENTER)) {
//                gjp.quit(playerNum);
//                gjp.stopGame();
//                stopRunning();
//            }
//        }
//    }
//
//    public void stopRunning() {
//        running = false;
//    }
//
//    @Override
//    public void run() {
//        st = System.currentTimeMillis();
//        ti = System.currentTimeMillis();
//        initGame();
//
//
//        while (running) {
//            if (restart) {
//                //清空集合
//                wall.clear();
//                bullet.clear();
//                player.clear();
//                bot.clear();
//                base.clear();
//                river.clear();
//                boom.clear();
//
//
//                restart = false;
//
//                initGame();
//
//                st = System.currentTimeMillis();
//                useTime = 0;
//                destroyCount = 0;
//            }
//
//            long t = System.currentTimeMillis();
//
//            checkEnd();
//
//            if (!end) {
//                checkStopState();  //检查游戏是否暂停
//                if (!stop) updateAll();  //更新所有状态
//            }
//
//            if (System.currentTimeMillis() - t < 16) {
//                try {
//                    Thread.sleep(16 - (System.currentTimeMillis() - t));
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }
//}

package com.scnu.hachimi.manager;

import com.scnu.hachimi.controller.KeyboardListener;
import com.scnu.hachimi.element.*;
import com.scnu.hachimi.show.GameJPanel;
import static com.scnu.hachimi.manager.MapLoader.getMap;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.ThreadLocalRandom;

public class ObjectManager extends Thread {
    // 游戏区域尺寸
    public int width = 800;
    public int height = 600;

    // 游戏状态
    public boolean stop = false;
    private boolean restart = false;
    private int stopOption = 1;
    public boolean end = false;
    private boolean win = true;

    // 游戏配置
    public int diff; // 难度
    private int playerNum; // 玩家数量
    public String mapFilePath; // 地图文件路径

    // 游戏统计
    public int destroyCount = 0;
    public long useTime = 0, st;
    public int Alive;
    private int batch = 1;

    // 游戏组件
    public GameJPanel gjp;

    // 游戏实体集合 (保持原变量名不变)
    public CopyOnWriteArrayList<Bot> bot = new CopyOnWriteArrayList<>();
    public CopyOnWriteArrayList<Player> player = new CopyOnWriteArrayList<>();
    public CopyOnWriteArrayList<Bullet> bullet = new CopyOnWriteArrayList<>();
    public CopyOnWriteArrayList<Wall> wall = new CopyOnWriteArrayList<>();
    public CopyOnWriteArrayList<Base> base = new CopyOnWriteArrayList<>();
    public CopyOnWriteArrayList<River> river = new CopyOnWriteArrayList<>();
    public CopyOnWriteArrayList<Boom> boom = new CopyOnWriteArrayList<>();
    public CopyOnWriteArrayList<String> stopImage = new CopyOnWriteArrayList<>();
    public CopyOnWriteArrayList<String> endImage = new CopyOnWriteArrayList<>();

    // 键盘状态
    public ConcurrentHashMap<Integer, Boolean> kb = new ConcurrentHashMap<>();
    public ConcurrentHashMap<Integer, Long> keyTimeSet = new ConcurrentHashMap<>();

    //敌人总数
    public int enemyCount;

    // 暂停状态控制
    private boolean w = true, s = true;
    private boolean running = true;
    private double fn = 0, ti;
    private Map<String, List<Point>> mapData = new HashMap<>();

    public ObjectManager(int playerNum, int diff, String mapFilePath) {
        this.playerNum = playerNum;
        this.diff = diff;
        this.mapFilePath = mapFilePath;
        this.Alive = playerNum;

        // 初始化键盘状态
        for (int keyCode = 0; keyCode < 256; keyCode++) {
            kb.put(keyCode, false);
        }

        checkStopImage();
    }

    /**
     * 主游戏循环
     */
    @Override
    public void run() {
        st = System.currentTimeMillis();
        ti = System.currentTimeMillis();
        initGame();

        while (running) {
            if (restart) {
                // 重置游戏状态
                wall.clear();
                bullet.clear();
                player.clear();
                bot.clear();
                base.clear();
                river.clear();
                boom.clear();

                restart = false;
                batch = 1;
                destroyCount = 0;
                useTime = 0;
                Alive = playerNum;

                initGame();
                st = System.currentTimeMillis();
            }

            long frameStart = System.currentTimeMillis();

            // 检查游戏结束状态
            try {
                checkEnd();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            if (!end) {
                // 检查暂停状态
                try {
                    checkStopState();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

                // 更新游戏逻辑
                if (!stop) {
                    updateBullets();
                    checkBW();
                    checkBT();
                    checkBB();
                    updatePlayer();
                    updateBots();
                    checkBoom();
                    fn++;
                }
            }

            // 控制帧率 (约60FPS)
            long frameTime = System.currentTimeMillis() - frameStart;
            if (frameTime < 16) {
                try {
                    Thread.sleep(16 - frameTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 初始化游戏
     */
    private void initGame() {
        loadMap("map/" + mapFilePath);
        addPlayer();

        enemyCount = Arg.getBatchCount(1, diff) + Arg.getBatchCount(2, diff) + Arg.getBatchCount(3, diff) + mapData.get("elite").size() + mapData.get("BOSS").size();
    }

    /**
     * 加载地图
     */
    private void loadMap(String filePath) {
        try {
            mapData = getMap(filePath);



            for (Map.Entry<String, List<Point>> entry : mapData.entrySet()) {
                String terrainType = entry.getKey();
                List<Point> points = entry.getValue();

                switch (terrainType) {
                    case "BRICK":
                        for (Point p : points) {
                            wall.add(new Wall(terrainType, p.x, p.y, 1, false));
                        }
                        break;

                    case "GRASS":
                        for (Point p : points) {
                            wall.add(new Wall(terrainType, p.x, p.y, 1, true));
                        }
                        break;

                    case "IRON":
                        for (Point p : points) {
                            wall.add(new Iron(terrainType, p.x, p.y, 1, false));
                        }
                        break;

                    case "base":
                        for (Point p : points) {
                            base.add(new Base(terrainType, p.x, p.y, 10));
                        }
                        break;

                    case "RIVER":
                        for (Point p : points) {
                            river.add(new River(terrainType, p.x, p.y, 1));
                        }
                        break;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("Failed to load map: " + filePath, e);
        }
    }

    /**
     * 添加玩家
     */
    private void addPlayer() {
        Arg.PlayerParams playerParams = Arg.getPlayerParams(diff);

        // 单人模式
        if (playerNum == 1) {
            if (mapData.get("player1") != null && !mapData.get("player1").isEmpty()) {
                for (Point point : mapData.get("player1")) {
                    player.add(new Player("player1", point.x, point.y, 40, 40,
                            playerParams.speed, playerParams.attack, playerParams.reload,
                            playerParams.bulletSpeed, playerParams.bulletSize,
                            "player1_up", "player1_down", "player1_left", "player1_right",
                            Color.ORANGE, playerParams.hp, this));
                }
            } else if (mapData.get("player2") != null && !mapData.get("player2").isEmpty()) {
                for (Point point : mapData.get("player2")) {
                    player.add(new Player("player2", point.x, point.y, 40, 40,
                            playerParams.speed, playerParams.attack, playerParams.reload,
                            playerParams.bulletSpeed, playerParams.bulletSize,
                            "player2_up", "player2_down", "player2_left", "player2_right",
                            Color.magenta, playerParams.hp, this));
                }
            } else {
                Player p1 = new Player("player1", 0, 0, 40, 40,
                        playerParams.speed, playerParams.attack, playerParams.reload,
                        playerParams.bulletSpeed, playerParams.bulletSize,
                        "player1_up", "player1_down", "player1_left", "player1_right",
                        Color.ORANGE, playerParams.hp, this);
                deployTank(p1);
            }
        }
        // 双人模式
        else if (playerNum == 2) {
            if (mapData.get("player1") != null && !mapData.get("player1").isEmpty()) {
                for (Point point : mapData.get("player1")) {
                    player.add(new Player("player1", point.x, point.y, 40, 40,
                            playerParams.speed, playerParams.attack, playerParams.reload,
                            playerParams.bulletSpeed, playerParams.bulletSize,
                            "player1_up", "player1_down", "player1_left", "player1_right",
                            Color.ORANGE, playerParams.hp, this));
                }
            } else {
                Player p1 = new Player("player1", 0, 0, 40, 40,
                        playerParams.speed, playerParams.attack, playerParams.reload,
                        playerParams.bulletSpeed, playerParams.bulletSize,
                        "player1_up", "player1_down", "player1_left", "player1_right",
                        Color.ORANGE, playerParams.hp, this);
                deployTank(p1);
            }
            if (mapData.get("player2") != null && !mapData.get("player2").isEmpty()) {
                for (Point point : mapData.get("player2")) {
                    player.add(new Player("player2", point.x, point.y, 40, 40,
                            playerParams.speed, playerParams.attack, playerParams.reload,
                            playerParams.bulletSpeed, playerParams.bulletSize,
                            "player2_up", "player2_down", "player2_left", "player2_right",
                            Color.magenta, playerParams.hp, this));
                }
            } else {
                Player p2 = new Player("player2", 0, 0, 40, 40,
                        playerParams.speed, playerParams.attack, playerParams.reload,
                        playerParams.bulletSpeed, playerParams.bulletSize,
                        "player2_up", "player2_down", "player2_left", "player2_right",
                        Color.magenta, playerParams.hp, this);
                deployTank(p2);
            }
        }
    }

    /**
     * 部署坦克（玩家或敌人）
     */
    private void deployTank(Tank tank) {
        int maxAttempts = 100; // 防止无限循环

        for (int attempt = 0; attempt < maxAttempts; attempt++) {
            int x = ThreadLocalRandom.current().nextInt(width - tank.getW());
            int y = ThreadLocalRandom.current().nextInt(height - tank.getH());
            tank.setX(x);
            tank.setY(y);

            if (!tank.checkWallBorder(Direction.UP)) {
                if (tank instanceof Player) {
                    player.add((Player) tank);
                } else if (tank instanceof Bot) {
                    bot.add((Bot) tank);
                }
                return;
            }
        }

        // 无法找到合适位置，使用默认位置
        tank.setX(0);
        tank.setY(0);
        if (tank instanceof Bot) {
            bot.add((Bot) tank);
        }
    }

    /**
     * 添加敌人
     */
    private void addBots(int count, Arg.EnemyParams params, Color color) {
        for (int i = 0; i < count; i++) {
            Bot bot = new Bot(
                    "bot_up", 0, 0, 40, 40,
                    params.speed, params.hp, params.reload,
                    params.bulletSpeed, params.bulletSize,
                    "bot_up", "bot_down", "bot_left", "bot_right",
                    color, params.hp, this
            );
            deployTank(bot);
        }
    }

    /**
     * 添加每波敌人
     */
    private void addEnemies() {
        // 添加普通敌人
        int botCount = Arg.getBatchCount(batch, diff);
        addBots(botCount, Arg.getBotParams(diff), Color.BLUE);

        // 第2波添加精英敌人
        if (batch == 2) {
            Arg.EnemyParams eliteParams = Arg.getEliteParams(diff);
            if (mapData.get("elite") != null) {
                for (Point p : mapData.get("elite")) {
                    bot.add(new Bot(
                            "elite", p.x, p.y, 40, 40,
                            eliteParams.speed, eliteParams.hp, eliteParams.reload,
                            eliteParams.bulletSpeed, eliteParams.bulletSize,
                            "elite_up", "elite_down", "elite_left", "elite_right",
                            Color.RED, eliteParams.hp, this
                    ));
                }
            }
        }

        // 第3波添加Boss
        if (batch == 3) {
            Arg.EnemyParams bossParams = Arg.getBossParams(diff);
            if (mapData.get("BOSS") != null) {
                for (Point p : mapData.get("BOSS")) {
                    Bot BOSS = new Bot(
                            "BOSS", p.x, p.y, 40, 40,
                            bossParams.speed, bossParams.hp, bossParams.reload,
                            bossParams.bulletSpeed, bossParams.bulletSize,
                            "BOSS_up", "BOSS_down", "BOSS_left", "BOSS_right",
                            Color.RED, bossParams.hp, this);
                    BOSS.isBOSS = true;
                    bot.add(BOSS);
                }
            }
        }
    }

    /**
     * 更新子弹位置
     */
    private void updateBullets() {
        for (Bullet b : bullet) {
            b.move();
        }
    }

    /**
     * 更新玩家状态
     */
    private void updatePlayer() {
        // 玩家1控制 (WASD + 空格)
        int key = -1;
        long time = 0;
        Direction d = Direction.UP;

        if (player.get(0).isAlive) {
            if (kb.get(KeyEvent.VK_W) && (keyTimeSet.get(KeyEvent.VK_W) > time)) {
                time = keyTimeSet.get(KeyEvent.VK_W);
                key = KeyEvent.VK_W;
                d = Direction.UP;
            }
            if (kb.get(KeyEvent.VK_A) && keyTimeSet.get(KeyEvent.VK_A) > time) {
                time = keyTimeSet.get(KeyEvent.VK_A);
                key = KeyEvent.VK_A;
                d = Direction.LEFT;
            }
            if (kb.get(KeyEvent.VK_S) && keyTimeSet.get(KeyEvent.VK_S) > time) {
                time = keyTimeSet.get(KeyEvent.VK_S);
                key = KeyEvent.VK_S;
                d = Direction.DOWN;
            }
            if (kb.get(KeyEvent.VK_D) && keyTimeSet.get(KeyEvent.VK_D) > time) {
                time = keyTimeSet.get(KeyEvent.VK_D);
                key = KeyEvent.VK_D;
                d = Direction.RIGHT;
            }
            if (key != -1) {
                player.get(0).setImg(d);
                player.get(0).move(d);
            }

            if (kb.get(KeyEvent.VK_SPACE)) {
                player.get(0).attack();
            }
        }

        // 玩家2控制 (方向键 + 小键盘0)
        if (playerNum == 2 && player.get(1).isAlive) {
            key = -1;
            time = 0;
            if (kb.get(KeyEvent.VK_UP) && keyTimeSet.get(KeyEvent.VK_UP) > time) {
                time = keyTimeSet.get(KeyEvent.VK_UP);
                key = KeyEvent.VK_UP;
                d = Direction.UP;
            }
            if (kb.get(KeyEvent.VK_DOWN) && keyTimeSet.get(KeyEvent.VK_DOWN) > time) {
                time = keyTimeSet.get(KeyEvent.VK_DOWN);
                key = KeyEvent.VK_DOWN;
                d = Direction.DOWN;
            }
            if (kb.get(KeyEvent.VK_LEFT) && keyTimeSet.get(KeyEvent.VK_LEFT) > time) {
                time = keyTimeSet.get(KeyEvent.VK_LEFT);
                key = KeyEvent.VK_LEFT;
                d = Direction.LEFT;
            }
            if (kb.get(KeyEvent.VK_RIGHT) && keyTimeSet.get(KeyEvent.VK_RIGHT) > time) {
                time = keyTimeSet.get(KeyEvent.VK_RIGHT);
                key = KeyEvent.VK_RIGHT;
                d = Direction.RIGHT;
            }
            if (key != -1) {
                player.get(1).setImg(d);
                player.get(1).move(d);
            }

            if (kb.get(KeyEvent.VK_NUMPAD0)) {
                player.get(1).attack();
            }
        }
    }

    /**
     * 更新敌人状态
     */
    private void updateBots() {
        for (Bot b : bot) {
            b.autoMoveAndAttack();
        }
    }

    /**
     * 检测子弹与墙壁碰撞
     */
    private void checkBW() {
        List<Bullet> removeBullet = new ArrayList<>();
        List<Wall> removeWall = new ArrayList<>();
        for (Bullet b : bullet) {
            for (Wall w : wall) {
                if (b.getRect().intersects(w.getRect())) {
                    if (!w.canThrough) removeBullet.add(b);

                    if (w instanceof Iron) {
                        //TODO 等级高了才能摧毁铁墙
                    } else {
                        w.hp -= b.atk;
                        if (w.hp <= 0) removeWall.add(w);
                    }
                }
            }
        }

        bullet.removeAll(removeBullet);
        wall.removeAll(removeWall);
    }

    /**
     * 检测子弹与基地碰撞
     */
    private void checkBB() {
        List<Bullet> removeBullet = new ArrayList<>();
        for (Bullet b : bullet) {
            for (Base base : base) {
                if (b.getRect().intersects(base.getRect())) {
                    base.hp -= b.atk;
                    removeBullet.add(b);
                    if (base.hp <= 0) {
                        end = true;
                        win = false;
                        boom.add(new Boom("boom", b.getX(), b.getY(), 30, 30));
                    } else boom.add(new Boom("boom", b.getX(), b.getY(), 2, 2));
                }
            }
        }
        bullet.removeAll(removeBullet);
    }

    /**
     * 检测子弹与坦克碰撞
     */
    private void checkBT() {
        List<Bullet> removeBullet = new ArrayList<>();
        List<Bot> removeBot = new ArrayList<>();
        for (Bullet b : bullet) {

            // 边界检查
            if (b.getX() < -b.getH() || b.getX() > width ||
                    b.getY() < -b.getH() || b.getY() > height) {
                removeBullet.add(b);
                continue;
            }

            boolean hit = false;

            // 玩家被击中
            for (Player p : player) {
                if (p.isAlive && b.getRect().intersects(p.getRect()) && !b.isPlayer) {
                    removeBullet.add(b);
                    p.hp -= b.atk;

                    if (p.hp <= 0) {
                        boom.add(new Boom("boom", b.getX(), b.getY(), 30, 30));
                        p.isAlive = false;
                        Alive--;

                        if (Alive <= 0) {
                            win = false;
                            end = true;
                        }
                    } else {
                        boom.add(new Boom("boom", b.getX(), b.getY(), 2, 2));
                    }
                    hit = true;
                }
            }
            if (hit) continue;

            // 敌人被击中
            for (Bot bt : bot) {
                if (b.getRect().intersects(bt.getRect()) && b.isPlayer) {
                    removeBullet.add(b);
                    bt.hp -= b.atk;

                    if (bt.hp <= 0) {
                        removeBot.add(bt);
                        destroyCount++;
                        boom.add(new Boom("boom", b.getX(), b.getY(), 30, 30));
                    } else {
                        boom.add(new Boom("boom", b.getX(), b.getY(), 2, 2));
                    }
                }
            }
        }

        bullet.removeAll(removeBullet);
        bot.removeAll(removeBot);

        enemyCount -= removeBot.size();

        // 检查是否需要生成下一波敌人
        if (bot.isEmpty()) {
            if (batch <= 3) {
                addEnemies();
                batch++;
            } else {
                end = true;
            }
        }
    }

    /**
     * 更新爆炸效果
     */
    private void checkBoom() {
        List<Boom> removeBoom = new ArrayList<>();
        for (Boom b : boom) {
            if (b.life <= 0) {
                removeBoom.add(b);
            }
            b.move();
        }
        boom.removeAll(removeBoom);
    }

    /**
     * 检查暂停状态
     */
    private void checkStopState() throws IOException {
        if (kb.get(KeyEvent.VK_ESCAPE)) {
            stop = true;
        }

        if (stop) {
            // 暂停游戏时间
            useTime += System.currentTimeMillis() - st;
            st = System.currentTimeMillis();

            // 处理暂停菜单选择
            if (kb.get(KeyEvent.VK_W)) {
                if (w) {
                    stopOption = stopOption > 1 ? stopOption - 1 : stopOption;
                    checkStopImage();
                    w = false;
                }
            } else {
                w = true;
            }

            if (kb.get(KeyEvent.VK_S)) {
                if (s) {
                    stopOption = stopOption < 3 ? stopOption + 1 : stopOption;
                    checkStopImage();
                    s = false;
                }
            } else {
                s = true;
            }

            // 确认选择
            if (kb.get(KeyEvent.VK_ENTER)) {
                stop = false;

                if (stopOption == 2) {
                    // 重新开始
                    restart = true;
                }
                if (stopOption == 3) {
                    // 退出游戏
                    gjp.quit(playerNum);
                    gjp.stopGame();
                    stopRunning();
                }
            }
        }
    }

    /**
     * 更新暂停菜单图片
     */
    private void checkStopImage() {
        stopImage.clear();
        stopImage.add("sp" + stopOption);
    }

    /**
     * 检查游戏结束状态
     */
    private void checkEnd() throws IOException {
        if (end) {
            if (useTime == 0) {
                useTime += System.currentTimeMillis() - st;
            }

            if (endImage.isEmpty()) {
                endImage.add(win ? "win" : "lose");
            }

            // 按Enter键退出
            if (kb.get(KeyEvent.VK_ENTER)) {
                gjp.quit(playerNum);
                gjp.stopGame();
                stopRunning();
            }
        }
    }

    /**
     * 停止游戏
     */
    public void stopRunning() {
        running = false;
    }
}